package org.kuan.lab.base.util;

import org.aspectj.lang.JoinPoint;
//import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
//import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Project: erp<br>
 * Description: 性能监测，使用Spring aop拦截方法，监测每个方法执行时间，超长的给予提示<br>
 * Copyright (c) 2012<br>
 * All Rights Reserved.<br>
 * @author <a href="mailto:gly420@163.com">GuanLuYong</a><br>
 */
@Aspect
public class MonitorPerformance {
	private final Logger log = LoggerFactory.getLogger(getClass());
	private long startMillions;

	@SuppressWarnings("unused")
	@Pointcut("execution(* org.deva.erp.common.controller..*.*(..))")
	private void doAction() { }
	
	@Before("doAction()")
	public void doActionBefore(JoinPoint jp) {
		this.startMillions = System.currentTimeMillis();
		// intercept Class
		Object target = jp.getTarget();
		log.info("INFO:The method which named [" +
				target.getClass().getPackage() + "." + target.getClass().getName() + "." +
				jp.getSignature().getName() + "] is star.");
	}
	
	@After("doAction()")
	public void doActionAfter(JoinPoint jp) {
		long useMillions = System.currentTimeMillis() - startMillions;
		if(useMillions > 2000) {	//out of time(2 seconds)
			log.warn("WARN:The Method which named [" +
					jp.getTarget().getClass().getPackage() + "." + jp.getTarget().getClass().getName() + "." +
					jp.getSignature().getName() + "] has out of TWO seconds when it was runned.");
		} else {
			log.info("INFO:The Method which named [" +
					jp.getTarget().getClass().getPackage() + "." + jp.getTarget().getClass().getName() + "." +
					jp.getSignature().getName() + "] is running.");
		}
	}
	
	@AfterThrowing(pointcut = "doAction()", throwing = "ex")
	public void doActionThrowException(JoinPoint jp, Exception ex) {
		log.error("ERROR:The Method which named [" +
					jp.getTarget().getClass().getPackage() + "." + jp.getTarget().getClass().getName() + "." +
					jp.getSignature().getName() + "]  has got an error.");
	}
	
//	@Around("doAction()")
//	public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
//		return pjp.proceed();
//	}
}
